package com.xlx.ui.service;


import cn.hutool.captcha.generator.RandomGenerator;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.sun.mail.util.MailSSLSocketFactory;
import com.xlx.ui.domain.DTO.UserDTO;
import com.xlx.ui.domain.MO.Friends;
import com.xlx.ui.domain.MO.User;
import com.xlx.ui.domain.VO.ResultBody;
import com.xlx.ui.mapper.FriendsMapper;
import com.xlx.ui.mapper.UserMapper;
import com.xlx.ui.service.error.errorImpl.BizException;
import com.xlx.ui.service.error.errorImpl.ResponseCodeEnum;
import com.xlx.ui.util.RedisUtils;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.util.Sqls;

import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author:
 * @date: 2020-11-30 21:31
 */
@Slf4j
@Service
public class UserService {
    private UserMapper userMapper;
    private RedisUtils redisUtils;
    private FriendsMapper friendsMapper;

    @Value("${user.photo}")
    private String path;

    public UserService(UserMapper userMapper, RedisUtils redisUtils,FriendsMapper friendsMapper) {
        this.userMapper = userMapper;
        this.redisUtils = redisUtils;
        this.friendsMapper=friendsMapper;
    }

    public ResultBody login(UserDTO userDTO) {
        if (StrUtil.isBlank(userDTO.getEmail()) || StrUtil.isBlank(userDTO.getPassword())) {
            throw new BizException(ResponseCodeEnum.PARAMETER_INVALID);
        }
        Example example = Example.builder(User.class)
                .where(Sqls.custom()
                        .andEqualTo("email", userDTO.getEmail())
                        .andEqualTo("password", SecureUtil.sha256("xlx" + userDTO.getPassword()))).build();
        List<User> users = userMapper.selectByExample(example);
        if (!users.isEmpty()) {
            User user = users.get(0);
            if (!user.getState()) {
                throw new BizException(ResponseCodeEnum.USER_DISABLE);
            }
            return ResultBody.success(user);
        } else {
            throw new BizException(ResponseCodeEnum.USER_NULL);
        }
    }

    /**
     * 注册
     *
     * @param userDTO
     * @return
     */
    public ResultBody register(UserDTO userDTO) {
        Object getCode = redisUtils.get(userDTO.getEmail());
        if (StrUtil.isBlank(getCode.toString())) {
            throw new BizException(ResponseCodeEnum.EMAIL_NOT_CODE);
        } else if (!getCode.equals(userDTO.getCode())) {
            throw new BizException(ResponseCodeEnum.EMAIL_NOT);
        } else {
            List<User> users = userMapper.selectByExample(Example.builder(User.class).where(Sqls.custom().andEqualTo("email", userDTO.getEmail())).build());
            if (!users.isEmpty()) {
                throw new BizException(ResponseCodeEnum.USER_EXIST);
            }
            User user = new User();
            user.setName(userDTO.getName());
            user.setEmail(userDTO.getEmail());
            user.setPassword(SecureUtil.sha256("xlx" + userDTO.getPassword()));
            user.setState(true);
            user.setCreateDate(new Date());
            user.setAuth(1);
            userMapper.insertSelective(user);
            return ResultBody.success(user);
        }
    }

    /**
     * 发送邮件
     *
     * @param email 邮件地址
     * @return
     */
    public ResultBody getEmailcode(String email) {
        List<User> users = userMapper.selectByExample(Example.builder(User.class).where(Sqls.custom().andEqualTo("email", email)).build());
        if (!users.isEmpty()) {
            throw new BizException(ResponseCodeEnum.EMAIL_NOT_NULL);
        } else {
            return sendEmail(email) ? ResultBody.success("邮件发送成功") : ResultBody.error(500, "邮件发送失败");
        }
    }

    /**
     * 发送邮箱
     *
     * @param to 目标邮箱地址
     * @return
     */
    public boolean sendEmail(String to) {
        Properties prop = new Properties();
        prop.setProperty("mail.host", "smtp.qq.com");
        prop.setProperty("mail.smtp.auth", "true");
        prop.setProperty("mail.transport.protocol", "smtp");
        MailSSLSocketFactory sf = null;
        try {
            sf = new MailSSLSocketFactory();
            sf.setTrustAllHosts(true);
            prop.put("mail.smtp.ssl.enable", "true");
            prop.put("mail.smtp.ssl.socketFactory", sf);
            Session session = Session.getInstance(prop);
            Transport ts = session.getTransport();
            ts.connect("smtp.qq.com", "2256222053@qq.com", "fgsmwujyfektdifj");
            Message message = createSimpleMail(session, to);
            ts.sendMessage(message, message.getAllRecipients());
            ts.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 构建邮箱消息
     *
     * @param session
     * @param to      目标邮箱地址
     * @return
     */
    public MimeMessage createSimpleMail(Session session, String to) {
        //创建邮件
        MimeMessage message = new MimeMessage(session);
        RandomGenerator randomGenerator = new RandomGenerator("0123456789", 4);
        String random = randomGenerator.generate();
        try {
            //发件人
            message.setFrom(new InternetAddress("2256222053@qq.com"));
            //收件人
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(to));
            message.setSubject("注册验证");
            //邮件正文
            MimeBodyPart text = new MimeBodyPart();
            text.setContent("<div style=\"margin: 0 auto; box-shadow: 0 0 10px #c4c4c4; border-radius: 10px; width: 500px;height: 200px;background-color: rgb(255, 255, 255);text-align: center;\"><h2 style=\"padding-top: 10px;\">注册验证</h2><p style=\"color: #555555;\">欢迎使用XH Yun,感谢您的注册，在使用过程中有疑问,可联系作者。</p><span style=\"display: inline-block; padding: 5px 15px; border: 2px #2777f8 dashed;font-weight: bold;\">" + random + "</span></div>", "text/html;charset=UTF-8");
            //描述数据关系
            MimeMultipart mm = new MimeMultipart();
            mm.addBodyPart(text);
            mm.setSubType("related");
            message.setContent(mm);
            message.saveChanges();
            redisUtils.set(to, random, 60 * 5);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return message;
    }


    public User getUser(String email) {
        List<User> users = userMapper.selectByExample(Example.builder(User.class).where(Sqls.custom().andEqualTo("email", email)).build());
        if (users.isEmpty()) {
            throw new BizException(ResponseCodeEnum.USER_NOT_EXIST);
        } else {
            User user = users.get(0);
            user.setPassword(null);
            return user;
        }
    }

    public boolean update(UserDTO userDTO) {
        if (userDTO.getEmail() != null) {
            List<User> users = userMapper.selectByExample(Example.builder(User.class).where(Sqls.custom().andEqualTo("email", userDTO.getEmail())
                    .andNotEqualTo("id", userDTO.getId())).build());
            if (!users.isEmpty()) {
                throw new BizException(ResponseCodeEnum.USER_EXIST);
            }
        }
        User user = new User();
//        if (userDTO.getPassword() != null) {
//            user.setPassword(SecureUtil.sha256("xlx" + userDTO.getPassword()));
//        }
        user.setEmail(userDTO.getEmail());
        user.setName(userDTO.getName());
        user.setId(userDTO.getId());
        user.setState(userDTO.getState());
        user.setAuth(userDTO.getAuth());
        int i = userMapper.updateByPrimaryKeySelective(user);
        return i > 0;
    }

    public ResultBody getAll() {
        List<User> users = userMapper.selectAll();
        return ResultBody.success(users);
    }

    public ResultBody del(String id) {
        int i = userMapper.deleteByPrimaryKey(id);
        return i > 0 ? ResultBody.success() : ResultBody.error(ResponseCodeEnum.DELETE_ERROR);
    }

    public String photo(MultipartFile picture, Integer userId) {
        try {
            File filePath = new File(path);
            if (!filePath.exists() && !filePath.isDirectory()) {
                filePath.mkdir();
            }
            //获取原始文件名称(包含格式)
            String originalFileName = picture.getOriginalFilename();
            //获取文件类型，以最后一个`.`为标识
            String type = originalFileName.substring(originalFileName.lastIndexOf(".") + 1);
            //获取文件名称（不包含格式）
            String name = originalFileName.substring(0, originalFileName.lastIndexOf("."));
            //设置文件新名称: 当前时间+文件名称（不包含格式）
            Date d = new Date();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
            String date = sdf.format(d);
            String fileName = date + name + "." + type;
            System.out.println("新文件名称：" + fileName);
            //在指定路径下创建一个文件
            File targetFile = new File(path, fileName);
            //将文件保存到服务器指定位置
            picture.transferTo(targetFile);
            //将文件在服务器的存储路径返回
            User user = userMapper.selectByPrimaryKey(userId);
            String oldPath = path+user.getPhoto();
            if(new File(oldPath).exists()){
                FileUtil.del(oldPath);
            }
            userMapper.updateByPrimaryKeySelective(User.builder().id(userId).photo("/"+fileName).build());
            return "/"+fileName;
        } catch (FileNotFoundException e) {
            log.error("上传照片失败:{}",e.getMessage());
            throw new BizException(ResponseCodeEnum.PHOTO_ERROR);
        } catch (IOException e) {
            log.error("上传照片失败:{}",e.getMessage());
            throw new BizException(ResponseCodeEnum.PHOTO_ERROR);
        }
    }


    //搜索用户并排除已添加的好友
    public List<User> search(Integer userId, String query) {
        query = "%"+query+"%";
        Example where = Example.builder(User.class).where(Sqls.custom().andLike("email", query).orLike("name", query)).build();
        List<User> users = userMapper.selectByExample(where);
        users = users.stream().filter(user -> !user.getId().equals(userId)).collect(Collectors.toList());
        //过滤已添加的好友
        List<Friends> friends = friendsMapper.selectByExample(Example.builder(Friends.class).where(Sqls.custom().andEqualTo("userid", userId)).build());
        ArrayList<User> list = new ArrayList<>();
        users.forEach(user ->{
            if(friends.stream().filter(friends1 -> friends1.getFriendsid().equals(user.getId())).findAny().orElse(null) ==null){
                list.add(user);
            }
        });
        return list;
    }


    /**
     * 修改密码
     * @param userid
     * @param oldPassword
     * @param newPassword
     * @return
     */
    public boolean updatePassword(Integer userid, String oldPassword, String newPassword) {
        User user = userMapper.selectByPrimaryKey(userid);
        if(user.getPassword().equals(SecureUtil.sha256("xlx" + oldPassword))){
            User user1 = new User();
            user1.setId(userid);
            user1.setPassword(SecureUtil.sha256("xlx"+newPassword));
            userMapper.updateByPrimaryKeySelective(user1);
        }else{
            throw new BizException(ResponseCodeEnum.NAME_PASSWORD_ERROR);
        }
        return true;
    }
}














